package net.protocol.diameter.avp;

import net.protocol.diameter.dictionary.AVPFormat;
import net.protocol.diameter.dictionary.AVPRule;

import java.util.Collection;

/**
 * @author jinhongw@gmail.com
 */
public class Formatter {

    /**
     * Returns A formatted string of <code>AVP</code>
     * The string returned is of the form:
     *
     * <pre>
     * Proxy-Host (280,M,l=22) = www.google.com
     *
     * Proxy-Info (284,M,l=42) =
     *   Proxy-Host (280,M,l=22) = www.google.com
     *   Proxy-State (33,M,l=12) = good
     * <pre/>
     *
     * @param format Diameter AVP Format
     * @param avp Diameter AVP
     * @return A formatted string of <code>AVP</code>
     */
    @SuppressWarnings("unchecked")
	public static String format(AVPFormat format, AVP<?> avp) {
        if (format == null) return avp.toString();
        StringBuilder buf = new StringBuilder();
        buf.append((format == null) ? avp.getName() : format.getName());
        buf.append(" (");
        buf.append(toString(avp));
        buf.append(") = ");
        if (format.isGroup()) {
            Collection<AVP<?>> avps = (Collection<AVP<?>>) avp.getData();
            for (AVP<?> e : avps) {
                AVPRule rule = format.get(e.getVendorId(), e.getCode());
                if (rule == null) {
                    buf.append("\n  ").append(e);
                } else {
                    buf.append("\n  ").append(format(rule.getAVPFormat(), e));
                }
            }
        } else {
            buf.append(avp.getData());
        }
        return buf.toString();
    }

    private static String toString(AVP<?> avp) {
        StringBuilder buf = new StringBuilder();
        buf.append(avp.getCode()).append(",");
        buf.append(avp.isVendorId() ? "V" : "");
        buf.append(avp.isMandatory() ? "M" : "");
        buf.append(avp.isProtected() ? "P" : "");
        buf.append(",");
        if (avp.isVendorId()) {
            buf.append("v=").append(avp.getVendorId());
            buf.append(",");
        }
        buf.append("l=").append(avp.getLength());
        return buf.toString();
    }
}
